<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>
<script>
    function Cat(name, color) {
        // {}
        // {}[[Prototype]] = Cat.prototype
        // this -> {}

        this.name = name;
        this.color = color;

        // return this;
    }
    Cat.prototype.species = "猫科";
    Cat.prototype.call = function () {
        console.log("喵喵");
    }
    Cat.prototype.skill = function () {
        console.log("捉老鼠");
    }
    Cat.prototype.say = function () {
        // this指向调用此方法的实例化对象
        // console.log("this", this);
        console.log(this.name, this.color);
    }

    Object.prototype.a = 1;
    Object.prototype.b = 2;

</script>
<script>
    // valueOf()       返回实例化对象的值
    // toString()      将实例化对象转化为字符串
    // isPrototypeOf()   判断某个原型对象 是否存在于 某个实例化对象的原型链上
    // hasOwnProperty()  判断某个实例化上是否存在某个属性
    // propertyIsEnumerable() 判断某个实例化上的某个属性是否可以被枚举(循环遍历)

    // valueOf()   返回实例化对象的值
    // toString()   将实例化对象转化为字符串 
    var num = new Number(1);
    var str = new String("hello");
    var bool = true;
    var arr = [1, 2, 3];
    var obj = { a: 1, b: 2 };
    var Tom = new Cat("Tom", "colorfulのblack");


    // console.log(num.valueOf());
    // console.log(str.valueOf());
    // console.log(bool.valueOf());
    // console.log(arr.valueOf());
    // console.log(obj.valueOf());
    // console.log(Tom.valueOf());


    // 为啥就前四个不一样?  => 难道访问的不是同一个toString()么 ?
    // 是的!   => 字符串 数字 布尔值 数组的原型对象上 有自己的toString()  => 不会访问Object.prototype.toString

    // console.log(num)
    // console.log(str)
    // console.log(arr)

    // console.log(num.toString());  // "1"
    // console.log(str.toString());  // "hello"
    // console.log(bool.toString()); // "true"
    // console.log(arr.toString());  // "1,2,3"
    // console.log(obj.toString());  // "[object Object]"
    // console.log(Tom.toString());  // "[object Object]"

    // 为了保持统一 => 是否都可以访问Object.prototype.toString
    // console.log(Object.prototype.toString.call(num));
    // console.log(Object.prototype.toString.call(str));
    // console.log(Object.prototype.toString.call(bool));
    // console.log(Object.prototype.toString.call(arr));
    // console.log(Object.prototype.toString.call(obj));
    // console.log(Object.prototype.toString.call(Tom));

    // 判断数据是否是数组
    // console.log(Object.prototype.toString.call(arr) === "[object Array]");

    // 判断数据是否是纯对象数据 {a:1}
    // console.log(Object.prototype.toString.call(obj) === "[object Object]");
    // console.log(Object.prototype.toString.call(Tom) === "[object Object]");



    // isPrototypeOf()   判断某个构造函数的原型对象 是否存在于 某个实例化对象的原型链上

    // Tom的原型链
    // Tom -> Cat.prototype ->  Object.prototype -> null

    // console.log(Cat.prototype.isPrototypeOf(Tom));  // true
    // console.log(Object.prototype.isPrototypeOf(Tom));// true
    // console.log(Array.prototype.isPrototypeOf(Tom)); // false

    // 拓展 instanceof   判断 某个实例化对象的原型链上  是否存在  某个构造函数 的原型对象
    // console.log(Tom instanceof Cat);// true
    // console.log(Tom instanceof Object);// true

    // hasOwnProperty()  判断某个实例化上是否存在某个属性 (不查找原型链)
    // console.log(Tom.hasOwnProperty("name"));// true
    // console.log(Tom.hasOwnProperty("color"));// true
    // console.log(Tom.hasOwnProperty("species"));// false

    // 拓展 in  => 判断某个属性 是否存在于 某个实例化对象的原型链上
    // for (var key in Tom) { // 遍历原型链
    //     console.log(key);
    // }

    // console.log("name" in Tom); // true
    // console.log("species" in Tom);// true
    // console.log("a" in Tom);// true

    // propertyIsEnumerable() 判断某个实例化上的某个属性是否可以被枚举(循环遍历)(不查找原型链)
    console.log(Tom.propertyIsEnumerable("name"));
    console.log(Tom.propertyIsEnumerable("species"));
    console.log(Tom.propertyIsEnumerable("a"));









</script>

</html>